function SimpleUserBubble(param) {
try{

	var that = this;
	
	this.j_bubble_trigger = null;
	this.j_bubble = null;
	this.j_bubble_username = null;
	this.j_bubble_arrow_up = null;
	this.j_bubble_arrow_down = null;
	
	var open_bubble_data = null;
	var user_bubble_arrow_border_width = 5;
	var gap_between_trigger_and_bubble = 1;
	
	var minGapToViewportBorder = 20;
	
	function __construct(p) {
	try{
		for(pkey in p) {
			if(pkey[0] != "_") {
				that[pkey] = p[pkey];
			}
		}
		that.j_bubble_trigger.live("mouseenter", triggerMouseEnter).live("mouseleave", triggerMouseLeave);
	}catch(err) {
		alert(err);
	}
	}
	
	function triggerMouseEnter(e) {
	try{
		var user_bubble_data = jq(this).data("user-simple-bubble");
		open_bubble_data = { "user_data" : user_bubble_data.user_data, "j_trigger" : jq(this) };
		openBubble();
	}catch(err) {
		alert(err);
	}
	}

	function triggerMouseLeave(e) {
	try{
		closeBubble();
	}catch(err) {
		alert(err);
	}
	}
	
	function openBubble() {
	try{
		var u = open_bubble_data.user_data;
		var trigger = open_bubble_data.j_trigger;
		var trigger_username = u.username;
		that.j_bubble_username.text(trigger_username);
		
		var trigger_offset = trigger.offset();
		
		var viewPortHeight = jq(window).height();
		var viewportWidth = jq(window).width();
		
		var trigger_height = trigger.outerHeight();
		var trigger_width = trigger.outerHeight();
		
		var bubble_width = that.j_bubble.outerWidth();
		var bubble_height = that.j_bubble.outerHeight();
		
		var toViewportTopBorder = trigger_offset.top - jq(window).scrollTop();
		var toViewportBottomBorder = viewPortHeight - toViewportTopBorder - trigger_height;
		var toViewportLeftBorder = trigger_offset.left - jq(window).scrollLeft();
		var toViewportRightBorder = viewportWidth - toViewportLeftBorder - trigger_width;
		
		var bubble_top = 0;
		var bubble_left = 0;
		var bubble_arrow_left = 0;
		
		var verticalInterval = bubble_height + user_bubble_arrow_border_width + gap_between_trigger_and_bubble;
		
		if(((toViewportTopBorder - verticalInterval) >= minGapToViewportBorder) || toViewportTopBorder >= toViewportBottomBorder) {
			// above profile pic
			that.j_bubble_arrow_up.hide();
			that.j_bubble_arrow_down.show();
			bubble_top = trigger_offset.top - verticalInterval;
		}else {
			// below profile pic
			that.j_bubble_arrow_down.hide();
			that.j_bubble_arrow_up.show();
			bubble_top = trigger_offset.top + (trigger_height + user_bubble_arrow_border_width + gap_between_trigger_and_bubble);
		}
		
		var leftGap = toViewportLeftBorder - (bubble_width - trigger_width)/2;
		var rightGap = toViewportRightBorder - (bubble_width - trigger_width)/2;
		
		if((leftGap >= minGapToViewportBorder && rightGap >= minGapToViewportBorder) || (leftGap < minGapToViewportBorder && rightGap < minGapToViewportBorder)) {
			bubble_arrow_left = bubble_width/2 - user_bubble_arrow_border_width;
			bubble_left = trigger_offset.left - (bubble_width - trigger.width())/2;
		}else if(leftGap < minGapToViewportBorder && rightGap >= minGapToViewportBorder) {
			var leftBalance = minGapToViewportBorder - leftGap;
			leftBalance =Math.min(leftBalance, (bubble_width - trigger_width)/2);
			bubble_arrow_left = bubble_width/2 - user_bubble_arrow_border_width - leftBalance ;
			bubble_left = trigger_offset.left - (bubble_width - trigger.width())/2 + leftBalance;
			
		}else if(rightGap < minGapToViewportBorder && leftGap >= minGapToViewportBorder) {
			var rightBalance = minGapToViewportBorder - rightGap;
			rightBalance =Math.min(rightBalance, (bubble_width - trigger_width)/2);
			bubble_arrow_left = bubble_width/2 - user_bubble_arrow_border_width + rightBalance ;
			bubble_left = trigger_offset.left - (bubble_width - trigger.width())/2 - rightBalance;
		}
		
		that.j_bubble_arrow_up.css({ "left" : bubble_arrow_left + "px" });
		that.j_bubble_arrow_down.css({ "left" : bubble_arrow_left + "px" });
		that.j_bubble.css({ "top" : bubble_top + "px", "left" : bubble_left + "px" }).show();
		
	}catch(err) {
		alert(err);
	}
	}
	
	function closeBubble() {
	try{
		that.j_bubble.hide();
	}catch(err) {
		alert(err);
	}
	}
	
	__construct(param);
	
}catch(err) {
	alert(err);
}
}

	
